from dataclasses import dataclass
from datetime import datetime
from enum import Enum
from typing import Sequence, Any, Callable, Coroutine, TypeVar, Type

from fastapi import Depends
from pydantic import BaseModel, Field, create_model

from rosa.scarborough_fair import BaseResponse, PayloadData, signature_authentication, optional_signature_authentication, PaginationData, GetAllData, Status, StatusMap, \
    settings, GenericBaseResponse, logger, SiteException

PayloadData = PayloadData
signature_authentication = signature_authentication
optional_signature_authentication = optional_signature_authentication
logger = logger
SiteException = SiteException

DEPENDENCIES = Sequence[Depends] | None
BASE_MODEL_TYPE_VAR = TypeVar("BASE_MODEL_TYPE_VAR", bound=BaseModel)

RESPONSE_CALLABLE = Callable[..., Coroutine[Any, Any, BaseResponse]]
RESPONSE_CALLABLE_LIST = Callable[..., Coroutine[Any, Any, GenericBaseResponse[GetAllData]]]

REAL_DELETE = settings.REAL_DELETE


def generate_response_model(
        model_name: str,
        status: Status,
        code: tuple[type, Field] = None,
        success: tuple[type, Field] = None,
        message: tuple[type, Field] = None,
        data: tuple[type, Field] = (dict, Field(default={}))
) -> Type[BaseModel]:
    """
    生成响应模型
    :param model_name: 模型名称
    :param status: 状态类型
    :param code: 状态码
    :param success: 状态
    :param message: 消息
    :param data: 数据类型
    :return:
    """
    if code is None:
        code = (str, Field(default=status.code))
    if success is None:
        success = (bool, Field(default=status.success))
    if message is None:
        message = (str, Field(default=status.message))

    return create_model(model_name, code=code, success=success, message=message, data=data)


# 定义默认的响应模式
OnlySuper = generate_response_model("OnlySuper", StatusMap.ONLY_SUPERUSER)
ItemNotFound = generate_response_model("ItemNotFound", StatusMap.ITEM_NOT_FOUND)
MultipleResults = generate_response_model("MultipleResults", StatusMap.MULTIPLE_RESULTS_FOUND)
PrimaryKeyExisted = generate_response_model("PrimaryKeyExisted", StatusMap.PRIMARY_KEY_EXISTED)
CreateFailed = generate_response_model("CreateFailed", StatusMap.CREATE_FAILED)
UpdateFailed = generate_response_model("UpdateFailed", StatusMap.UPDATE_FAILED)
DeleteFailed = generate_response_model("DeleteFailed", StatusMap.DELETE_FAILED)
RemoteRequestFailed = generate_response_model("RemoteRequestFailed", StatusMap.REMOTE_REQUEST_FAILED)

# 为其他请求预留响应模式
ONLY_SUPERUSER_RESPONSE = {
    StatusMap.ONLY_SUPERUSER.http_code: {
        "model": OnlySuper,
        "description": "只有超级用户才能访问",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.ONLY_SUPERUSER.code,
                    "success": StatusMap.ONLY_SUPERUSER.success,
                    "message": StatusMap.ONLY_SUPERUSER.message,
                    "data": {}
                }
            }
        }
    }
}

ITEM_NOT_FOUND_RESPONSE = {
    StatusMap.ITEM_NOT_FOUND.http_code: {
        "model": ItemNotFound,
        "description": "数据不存在",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.ITEM_NOT_FOUND.code,
                    "success": StatusMap.ITEM_NOT_FOUND.success,
                    "message": StatusMap.ITEM_NOT_FOUND.message,
                    "data": {}
                }
            }
        }
    }
}

MULTIPLE_RESULTS_FOUND_RESPONSE = {
    StatusMap.MULTIPLE_RESULTS_FOUND.http_code: {
        "model": MultipleResults,
        "description": "找到多条数据",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.MULTIPLE_RESULTS_FOUND.code,
                    "success": StatusMap.MULTIPLE_RESULTS_FOUND.success,
                    "message": StatusMap.MULTIPLE_RESULTS_FOUND.message,
                    "data": {}
                }
            }
        }
    }
}

PRIMARY_KEY_EXISTED_RESPONSE = {
    StatusMap.PRIMARY_KEY_EXISTED.http_code: {
        "model": PrimaryKeyExisted,
        "description": "唯一数据已存在",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.PRIMARY_KEY_EXISTED.code,
                    "success": StatusMap.PRIMARY_KEY_EXISTED.success,
                    "message": StatusMap.PRIMARY_KEY_EXISTED.message,
                    "data": {}
                }
            }
        }
    }
}

CREATE_FAILED_RESPONSE = {
    StatusMap.CREATE_FAILED.http_code: {
        "model": CreateFailed,
        "description": "创建失败",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.CREATE_FAILED.code,
                    "success": StatusMap.CREATE_FAILED.success,
                    "message": StatusMap.CREATE_FAILED.message,
                    "data": {}
                }
            }
        }
    }
}

UPDATE_FAILED_RESPONSE = {
    StatusMap.UPDATE_FAILED.http_code: {
        "model": UpdateFailed,
        "description": "更新失败",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.UPDATE_FAILED.code,
                    "success": StatusMap.UPDATE_FAILED.success,
                    "message": StatusMap.UPDATE_FAILED.message,
                    "data": {}
                }
            }
        }
    }
}

DELETE_FAILED_RESPONSE = {
    StatusMap.DELETE_FAILED.http_code: {
        "model": DeleteFailed,
        "description": "删除失败",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.DELETE_FAILED.code,
                    "success": StatusMap.DELETE_FAILED.success,
                    "message": StatusMap.DELETE_FAILED.message,
                    "data": {}
                }
            }
        }
    }
}

REMOTE_REQUEST_FAILED_RESPONSE = {
    StatusMap.REMOTE_REQUEST_FAILED.http_code: {
        "model": RemoteRequestFailed,
        "description": "获取资源失败",
        "content": {
            "application/json": {
                "example": {
                    "code": StatusMap.REMOTE_REQUEST_FAILED.code,
                    "success": StatusMap.REMOTE_REQUEST_FAILED.success,
                    "message": StatusMap.REMOTE_REQUEST_FAILED.message,
                    "data": {}
                }
            }
        }
    }
}


class PAGINATION(PaginationData):
    max_limit: int = 10


class RecordStatus(Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    FROZEN = "frozen"
    OBSOLETE = "obsolete"


@dataclass
class GenerateRouterParams:
    summary: str = None
    description: str = None
    responses: dict = None
    response_model: Any = None

    def __post_init__(self):
        self.summary = self.summary or ""
        self.description = self.description or ""
        self.responses = self.responses or {}
        self.response_model = self.response_model or None


# 默认的查询模型需要包含的字段
class QueryBaseModel(BaseModel):
    id: int = Field(default=0, description="数据索引", title="数据索引")
    level: int = Field(default=1, description="排序等级", title="排序等级")
    status: RecordStatus = Field(default=RecordStatus.ACTIVE, description="数据状态", title="数据状态")
    create_time: datetime = Field(default=datetime.now(), description="创建时间", title="创建时间", examples=["2022-11-17T11:23:22.084108"])
    update_time: datetime = Field(default=datetime.now(), description="修改时间", title="修改时间", examples=["2022-11-17T11:23:22.084108"])


class UpdateAddFields(BaseModel):
    level: int = Field(default=1, description="排序等级", title="排序等级", gt=0)
    status: str = Field(default=RecordStatus.ACTIVE, description="数据状态", title="数据状态")
